package studio.raptor.extractor.segment;

import com.google.common.base.Joiner;
import java.util.concurrent.atomic.AtomicBoolean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import studio.raptor.extractor.segment.config.EventSourceConfig;
import studio.raptor.extractor.segment.config.ServerConfig;
import studio.raptor.extractor.segment.holder.ExtractorServerHolder;
import studio.raptor.extractor.segment.properties.MQProperties;
import studio.raptor.extractor.segment.properties.QueueProperties;
import studio.raptor.extractor.segment.properties.ThreadProperties;
import studio.raptor.extractor.segment.properties.ZKProperties;
import studio.raptor.extractor.segment.server.ExtractorServer;
import studio.raptor.extractor.segment.service.EventNodeService;
import studio.raptor.extractor.segment.service.EventSourceConfigService;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;

/**
 * Created by liuyong8 on 2017/8/7.
 */
@Component
public abstract class ExtractorServerInitializer implements ApplicationRunner {
    private static final Logger log = LoggerFactory.getLogger(ExtractorServerInitializer.class);

    @Autowired
    private MQProperties mqProperties;
    @Autowired
    private QueueProperties queueProperties;
    @Autowired
    private ThreadProperties threadProperties;

    @Autowired
    private EventSourceConfigService eventSourceConfigService;
    @Autowired
    private EventNodeService eventNodeService;

    @Autowired
    ApplicationContext context;

    @PostConstruct
    public void init(){
        System.out.println("init ExtractorServerInitializer");
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("extractor run kindId = {}", Joiner.on(",").join(mqProperties.getEventKindId()));

        for (Integer kindId: mqProperties.getEventKindId()){
            ServerConfig serverConfig = buildServerConfig(kindId);
            log.info("服务配置：" + serverConfig.toString());

            ExtractorServer server = buildExtractorServer(serverConfig);
            ExtractorServerHolder.addServer(server);
        }

        ExtractorServerHolder.startUp();
        // TODO 先支持一种场景，在支持多种场景

    }

    /**
     * 组装serverConfig对象
     * @param kindId kindId
     * @return serverConfig
     */
    private ServerConfig buildServerConfig(Integer kindId) throws Exception{
        ServerConfig serverConfig = new ServerConfig();
        EventSourceConfig eventSourceConfig = eventSourceConfigService.findEventSourceConfigByKindId(kindId);
        Map<String/*JsonElementName*/,String/*serverUrl*/> serverUrlMap = eventNodeService.findNodeInfosByKindId(kindId);
        serverConfig.setKindId(kindId);
        serverConfig.setEventName(eventSourceConfig.getEventName());
        serverConfig.setSort(eventSourceConfig.getEventSort());
        serverConfig.setDatabusKindId(eventSourceConfig.getDatabusKindId());
        serverConfig.setBizName(getBizName());

        serverConfig.setServerUrlMap(serverUrlMap);

        serverConfig.setOverTime(threadProperties.getOverTime());
        serverConfig.setEventQueueSize(queueProperties.getEventQueueSize());
        serverConfig.setEventDataQueueSize(queueProperties.getEventDataQueueSize());
        serverConfig.setBuildJsonQueueSize(queueProperties.getBuildJsonQueueSize());

        serverConfig.setExtractorMQEnabled(new AtomicBoolean(true));

        return serverConfig;
    }

    /**
     *
     * @param serverConfig
     * @return
     */
    private ExtractorServer buildExtractorServer(ServerConfig serverConfig) {
        ExtractorServer extractorServer = context.getBean(ExtractorServer.class);
        extractorServer.setServerConfig(serverConfig);
        return extractorServer;
    }

    abstract protected String getBizName();
}
